package com.example.teesystem.service.impl;

import cn.hutool.core.lang.Validator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.teesystem.common.cache.KnowledgeCache;
import com.example.teesystem.common.cache.UserCache;
import com.example.teesystem.common.exception.CustomException;
import com.example.teesystem.common.utils.CustomConvert;
import com.example.teesystem.common.utils.ResultCode;
import com.example.teesystem.entity.Chapter;
import com.example.teesystem.entity.Knowledge;
import com.example.teesystem.entity.vo.knowledge.ChapterKnowledgeResponseVO;
import com.example.teesystem.entity.vo.knowledge.KnowledgeResponseVo;
import com.example.teesystem.entity.vo.knowledge.KnowledgeUpdateVo;
import com.example.teesystem.entity.vo.knowledge.KnowledgeUploadVo;
import com.example.teesystem.mapper.ChapterMapper;
import com.example.teesystem.service.KnowledgeService;
import com.example.teesystem.mapper.KnowledgeMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 28131
* @description 针对表【t_knowledge】的数据库操作Service实现
* @createDate 2022-03-29 08:47:26
*/
@Service
@RequiredArgsConstructor
public class KnowledgeServiceImpl extends ServiceImpl<KnowledgeMapper, Knowledge>
    implements KnowledgeService{
    private final ChapterMapper chapterMapper;
    
    @Override
    public boolean add(KnowledgeUploadVo knowledgeUploadVo) {
        Knowledge knowledge = this.convertToKnowledge(knowledgeUploadVo);
        // 如果新知识点和父级知识点的章节 id 不一样 或 父知识点不存在则报错
        this.validKnowledge(knowledge);

        if(this.save(knowledge)) {
            KnowledgeCache.knowledgeMap.put(knowledge.getId(), this.getById(knowledge.getId()));
            return true;
        }
        return false;
    }
    
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean add(List<KnowledgeUploadVo> knowledgeUploadVos) {
        List<Knowledge> knowledgeList = knowledgeUploadVos.stream()
                .map(this::convertToKnowledge)
                .collect(Collectors.toList());
        
        if(this.saveBatch(knowledgeList)) {
            List<Integer> ids = knowledgeList.stream().map(Knowledge::getId).collect(Collectors.toList());
            this.listByIds(ids).forEach(knowledge -> KnowledgeCache.knowledgeMap.put(knowledge.getId(), knowledge));
            return true;
        }
        return false;
    }
    
    @Override
    public boolean update(KnowledgeUpdateVo knowledgeUpdateVo) {
        // 类型转换
        Knowledge knowledge = new Knowledge();
        BeanUtils.copyProperties(knowledgeUpdateVo, knowledge);
        if(Validator.isNotNull(knowledgeUpdateVo.getRelationKnowledge())) {
            knowledge.setRelationKnowledge(CustomConvert.convertToString(knowledgeUpdateVo.getRelationKnowledge()));
        }
        this.validKnowledge(knowledge);
        // 校验章节是否在课程下
        if(!chapterMapper.selectById(knowledge.getChapterId()).getCourseId().equals(knowledge.getCourseId())) {
            throw new CustomException(ResultCode.PARAMETER_ERROR);
        }
    
        // 更新流程
        if(this.updateById(knowledge)) {
            KnowledgeCache.knowledgeMap.put(knowledge.getId(), this.getById(knowledge.getId()));
            return true;
        }
        return false;
    }
    
//    @Override
//    public List<KnowledgeResponseVo> get(Integer courseId) {
//        // 从数据库获取所有知识点
//        QueryWrapper<Knowledge> wrapper = new QueryWrapper<>();
//        wrapper.eq("course_id", courseId);
//        List<Knowledge> knowledgeList = this.list(wrapper);
//
//        // 对所有知识点进行封装
//        return knowledgeList.stream()
//                .filter(knowledge -> knowledge.getParentId() == 0)                                      // 筛选出父级节点 （parentId 为 0）
//                .map(knowledge -> {
//                    KnowledgeResponseVo knowledgeResponseVo = this.customCopyProperties(knowledge);     // 封装其他属性
//                    knowledgeResponseVo.setChildren(this.getChildren(knowledge, knowledgeList));        // 封装子结点
//                    return knowledgeResponseVo;
//                })
//                .collect(Collectors.toList());
//    }
    
    @Override
    public List<ChapterKnowledgeResponseVO> getChapterKnowledge(Integer courseId) {
        // 获取章节
        List<Chapter> chapters = chapterMapper.selectAllByCourseIdOrderByChapter(courseId);
    
        // 从数据库获取所有知识点
        QueryWrapper<Knowledge> wrapper = new QueryWrapper<>();
        wrapper.eq("course_id", courseId);
        List<Knowledge> knowledgeList = this.list(wrapper);
        
        // 封装知识点
        List<ChapterKnowledgeResponseVO> result = new ArrayList<>();
        for(Chapter chapter : chapters) {
            ChapterKnowledgeResponseVO responseVO = new ChapterKnowledgeResponseVO();
            BeanUtils.copyProperties(chapter, responseVO);
            // 封装该章节下的知识点列表
            List<KnowledgeResponseVo> knowledgeResponseVoList = knowledgeList.stream()
                    .filter(knowledge -> knowledge.getChapterId().equals(responseVO.getId()) && knowledge.getParentId() == 0)
                    .map(knowledge -> {
                        KnowledgeResponseVo knowledgeResponseVo = new KnowledgeResponseVo();
                        BeanUtils.copyProperties(knowledge, knowledgeResponseVo);
                        knowledgeResponseVo.setChildren(this.getChildren(knowledge, knowledgeList, responseVO.getId()));
                        return knowledgeResponseVo;
                    })
                    .collect(Collectors.toList());
            responseVO.setKnowledgeList(knowledgeResponseVoList);
            result.add(responseVO);
        }
    
        return result;
    }
    
    
    @Override
    public boolean delete(Integer id) {
        // 如果有子知识点则不进行删除
        QueryWrapper<Knowledge> knowledgeQueryWrapper = new QueryWrapper<>();
        knowledgeQueryWrapper.eq("parent_id", id);
        if(this.count(knowledgeQueryWrapper) > 0) {
            return false;
        }
        
        if(this.removeById(id)) {
            KnowledgeCache.knowledgeMap.remove(id);
            return true;
        }
        return false;
    }
    
    /**
     * 获取当前知识点的子知识点
     * @param knowledge 当前知识点
     * @param knowledgeList 所有的知识点
     * @return
     */
//    private List<KnowledgeResponseVo> getChildren(Knowledge knowledge, List<Knowledge> knowledgeList) {
//        return knowledgeList.stream()
//                .filter(child -> child.getParentId().equals(knowledge.getId()))                         // 筛选出子结点
//                .map(child -> {
//                    KnowledgeResponseVo knowledgeResponseVo = this.customCopyProperties(child);         // 封装其他属性
//                    knowledgeResponseVo.setChildren(this.getChildren(child, knowledgeList));            // 封装子结点
//                    return knowledgeResponseVo;
//                })
//                .collect(Collectors.toList());
//    }
    private List<KnowledgeResponseVo> getChildren(Knowledge knowledge, List<Knowledge> knowledgeList, Integer chapterId) {
        return knowledgeList.stream()
                .filter(k -> k.getChapterId().equals(chapterId) && k.getParentId().equals(knowledge.getId()))
                .map(k -> {
                    KnowledgeResponseVo knowledgeResponseVo = new KnowledgeResponseVo();
                    BeanUtils.copyProperties(k, knowledgeResponseVo);
                    knowledgeResponseVo.setChildren(this.getChildren(k, knowledgeList, chapterId));
                    return knowledgeResponseVo;
                })
                .collect(Collectors.toList());
    }
    
//    /**
//     * 转化成 responseVo
//     * @param knowledge 知识点
//     * @return
//     */
//    private KnowledgeResponseVo customCopyProperties(Knowledge knowledge) {
//        KnowledgeResponseVo knowledgeResponseVo = new KnowledgeResponseVo();
//        BeanUtils.copyProperties(knowledge, knowledgeResponseVo);
//
////        knowledgeResponseVo.setUploadName(UserCache.userMap.get(knowledge.getUploadId()).getMyName());
////        knowledgeResponseVo.setUpdateName(UserCache.userMap.get(knowledge.getUpdateId()).getMyName());
//        knowledgeResponseVo.setRelationKnowledge(CustomConvert.convertToList(knowledge.getRelationKnowledge()));
//
//        return knowledgeResponseVo;
//    }
    
    /**
     * 转化成 knowledge
     * @param knowledgeUploadVo 上传 vo
     * @return
     */
    private Knowledge convertToKnowledge(KnowledgeUploadVo knowledgeUploadVo) {
        Knowledge knowledge = new Knowledge();
        BeanUtils.copyProperties(knowledgeUploadVo, knowledge);
        
        knowledge.setParentId(knowledgeUploadVo.getParentId() != null ? knowledgeUploadVo.getParentId() : 0);
        if(Validator.isNotNull(knowledgeUploadVo.getRelationKnowledge())) {
            knowledge.setRelationKnowledge(CustomConvert.convertToString(knowledgeUploadVo.getRelationKnowledge()));
        }
        
        return knowledge;
    }
    
    /**
     * 校验知识点是否满足要求
     * @param knowledge 知识点
     */
    private void validKnowledge(Knowledge knowledge) {
        if(knowledge.getParentId() != null && knowledge.getParentId() != 0) {
            Knowledge parentKnowledge = KnowledgeCache.knowledgeMap.get(knowledge.getParentId());
            if(parentKnowledge == null) {
                throw new CustomException(ResultCode.PARENT_KNOWLEDGE_NOT_EXIST);
            }
            if(!parentKnowledge.getChapterId().equals(knowledge.getChapterId())) {
                throw new CustomException(ResultCode.KNOWLEDGE_CHAPTER_NOT_SAME);
            }
        }
    }
}
